<template>
  <!-- 新增部门的弹层 -->
  <el-dialog
    ref="dialog"
    :title="title"
    :visible="dialogFormVisible"
    @close="closeFn"
  >
    <!-- 表单组件  el-form   label-width设置label的宽度   -->
    <!-- 匿名插槽 -->
    <el-form
      ref="ruleForm"
      :model="form"
      :rules="rules"
      label-width="120px"
    >
      <el-form-item
        prop="name"
        label="部门名称"
      >
        <el-input
          v-model="form.name"
          style="width:80%"
          placeholder="1-50个字符"
        />
      </el-form-item>
      <el-form-item
        prop="code"
        label="部门编码"
      >
        <el-input
          v-model="form.code"
          style="width:80%"
          placeholder="1-50个字符"
        />
      </el-form-item>
      <el-form-item
        prop="manager"
        label="部门负责人"
      >
        <el-select
          v-model="form.manager"
          style="width:80%"
          placeholder="请选择"
          @blur="checkManager"
        >
          <el-option
            v-for="item in principals"
            :key="item.id"
            :label="item.username"
            :value="item.username"
          />
        </el-select>
      </el-form-item>
      <el-form-item
        prop="introduce"
        label="部门介绍"
      >
        <el-input
          v-model="form.introduce"
          style="width:80%"
          placeholder="1-300个字符"
          type="textarea"
          :rows="3"
        />
      </el-form-item>
    </el-form>
    <!-- el-dialog有专门放置底部操作栏的 插槽  具名插槽 -->
    <el-row
      slot="footer"
      type="flex"
      justify="center"
    >
      <!-- 列被分为24 -->
      <el-col :span="6">
        <el-button
          type="primary"
          size="small"
          @click="improvementFn"
        >确定</el-button>
        <el-button
          size="small"
          @click="closeFn"
        >取消</el-button>
      </el-col>
    </el-row>
  </el-dialog>
</template>

<script>
import { getRoleList } from '@/api/user'
import {
  addDepartment,
  updateDepartment,
  getDepartmentList
} from '@/api/company'
export default {
  props: {
    title: {
      type: String,
      required: true
    },
    companyId: {
      type: String,
      default: ''
    }
  },
  data() {
    //   !设置部门编码校验
    const isRepeatCode = async(rule, val, callback) => {
      // 获取所有部门的信息
      const { depts } = await this.getDepartmentInfo()
      //   区分编辑和新增场景
      let isRepeat
      if (this.form.id) {
        //   !编辑
        isRepeat = depts.some(
          // 判断用户输入的编码排除自己之外的数据中是否已经存在
          (item) => item.code === val && item.id !== this.form.id
        )
      } else {
        //   !新增
        //   通过数组的 some方法筛选出用户输入的编码是否有相同的编码
        isRepeat = depts.some((item) => item.code === val)
      }

      //   如果有则提示用户部门编码必须唯一，不能通过
      if (isRepeat) {
        callback(new Error('部门编码必须唯一'))
      } else {
        //   反之，则通过
        callback()
      }
    }
    // !设置子部门在当前部门的名称是否有重复校验
    const isRepeatName = async(rule, val, callback) => {
      // 获取所有部门的信息
      const { depts } = await this.getDepartmentInfo()
      //   筛选出同一部门的子部门
      let isRepeat
      if (this.form.id) {
        //   !编辑
        // 筛选出在同一个部门的所有子部门
        const res = await depts.filter((item) => this.form.pid === item.pid)
        //   通过数组的 some方法筛选出用户输入的名称在同一部门是否有相同的名称
        isRepeat = res.some(
          // 判断用户输入的部门名称在排除自己本身的名称之外的数据是否还含有同样的部门名称
          (item) => item.name === val && item.id !== this.form.id
        )
      } else {
        //   !新增
        //  筛选出本部门的所有子部门
        const res = await depts.filter((item) => this.form.pid === item.id)
        //   通过数组的 some方法筛选出用户输入的名称在同一部门是否有相同的名称
        isRepeat = res.some((item) => item.name === val)
      }
      if (isRepeat) {
        //   如果有，则不允许通过，并提示用户名称不能重复
        callback(new Error('子部门名称不能重复'))
      } else {
        //   反之，则允许通过
        callback()
      }
    }
    return {
      dialogFormVisible: false,
      principals: null,
      form: {
        name: '',
        code: '',
        manager: '',
        introduce: '',
        pid: ''
      },
      rules: {
        name: [
          { required: true, message: '名字不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 50,
            message: '部门名称要求 1~50 个字符',
            trigger: 'blur'
          },
          { validator: isRepeatName, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 50,
            message: '部门编码要求 1~50 个字符',
            trigger: 'blur'
          },
          { validator: isRepeatCode, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: 'blur' }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: 'blur' },
          {
            min: 1,
            max: 300,
            message: '部门介绍要求 1~300 个字符',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  async created() {
    this.principals = await getRoleList()
  },
  methods: {
    async improvementFn() {
      // 表单验证
      await this.$refs.ruleForm.validate()
      if (this.title === '新增部门') {
        await addDepartment(this.form)
        this.$message({
          message: '新增成功',
          type: 'success'
        })
      } else {
        await updateDepartment(this.form.id, this.form)
        this.$message({
          message: '修改成功',
          type: 'success'
        })
      }

      //   通过事件总线，更新页面数据
      this.$bus.$emit('update')
      this.dialogFormVisible = false
    },
    closeFn() {
      // 将数据重置为初始值,并移除校验结果的函数
      this.form = {
        name: '',
        code: '',
        manager: '',
        introduce: '',
        pid: ''
      }
      // resetFields 只能怪清理被绑定过的默认值
      // 还可以清理报错提示
      this.$refs.ruleForm.resetFields()
      //   关闭弹窗
      this.dialogFormVisible = false
    },
    // 负责人校验
    checkManager() {
      setTimeout(() => {
        this.$refs.ruleForm.validateField('manager')
      }, 100)
    },
    async getDepartmentInfo() {
      return await getDepartmentList()
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep.el-dialog .el-dialog__header {
  background-color: rgb(100, 159, 222);
}
</style>

